#!/bin/bash

# Note:This script assumes the user has the permission to ssh into the master machine.
# Variables:
machineip=
masterip=
tokensha=
token=
hostname=`hostname`
kubeversion=`sudo kubeadm version -o short`
kuberegex='^v1[.][0-7][.][0-9][0-9]?$'

function get_machine_ip(){
    ip addr show \
    | grep -oP "inet \\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}" \
    | grep -oP "\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}" | sort \
    | tail -n 1 | head -n 1
}

function update_hosts(){
    sudo sed -i "/$hostname/ s/.*/$machineip\t$hostname/g" /etc/hosts
}

function setup_k8s_minion(){

    [[ $kubeversion =~ $kuberegex ]]
    # For versions 1.8 and above, discovery token SHA is necessary to join the master
    if [[ $? -eq 1 ]]; then
        echo Setting up the Minion using Discovery Token SHA: $tokensha

        sudo iptables -F && sudo iptables -t nat -F && sudo iptables -t mangle -F && sudo iptables -X

        sudo kubeadm join --token=$token ${masterip}:6443 --discovery-token-ca-cert-hash sha256:${tokensha}
    else
        
        sudo iptables -F && sudo iptables -t nat -F && sudo iptables -t mangle -F && sudo iptables -X

        sudo kubeadm join --token=$token ${masterip}:6443
    fi
    
}

function disable_swap()
{    
    sudo swapoff -a

    sudo sed -i.bak '/ swap / s/^\(.*\)$/#\1/g' /etc/fstab
    
    cat <<EOF | sudo tee -a /etc/systemd/system/kubelet.service.d/90-local-extras.conf > /dev/null
    Environment="KUBELET_EXTRA_ARGS=--fail-swap-on=false"
EOF
    sudo systemctl daemon-reload
    sudo systemctl restart kubelet
}

function show_help() {
    cat << EOF
    Usage : $(basename "$0") --masterip=<KubeMaster IP> --token=<Token> --token-sha=<Discovery-Token SHA>
    Create a Kubernetes Minion Node and Join the cluster.
    
    -h|--help                    Display this help and exit.
    -i|--masterip Kubemaster IP  IP of kubemaster to join the cluster.
    -t|--token Token             Token generated by kubeadm init.
    -s|--token-sha SHA           Discovery Token SHA for the Cluster.
EOF
}

# Code:
# Check whether we received the User and Master hostnames else Show usage
# Uses the long form of arguments now

if (($# == 0)); then
    show_help
    exit 2
fi

while :; do
    case $1 in
        -h|-\?|--help)  # Call a "show_help" function to 
                        # display a synopsis, then exit.
                        show_help
                        exit
                        ;;
        
        -i|--masterip)  # Takes an option argument, 
                        # ensuring it has been specified.
                        if [ -n "$2" ]; then
                            masterip=$2
                            shift
                        else
                            printf 'ERROR: "--masterip" requires \
                            a non-empty option argument.\n' >&2
                            exit 1
                        fi
                        ;;
        
        --masterip=?*)  # Delete everything up to "=" 
                        # and assign the remainder.
                        masterip=${1#*=} 
                        ;;
        
        --masterip=)    # Handle the case of an empty --masterip=
                        printf 'ERROR: "--masterip" requires \
                        a non-empty option argument.\n' >&2
                        exit 1
                        ;;

        -t|--token)     # Takes an option argument, 
                        # ensuring it has been specified.
                        if [ -n "$2" ]; then
                            token=$2
                            shift
                        else
                            printf 'ERROR: "--token" requires \
                            a non-empty option argument.\n' >&2
                            exit 1
                        fi
                        ;;
        
        --token=?*)     # Delete everything up to "=" 
                        # and assign the remainder.
                        token=${1#*=} 
                        ;;
        
        --token=)       # Handle the case of an empty --token=
                        printf 'ERROR: "--token" requires \
                        a non-empty option argument.\n' >&2
                        exit 1
                        ;;

        -s|--token-sha) # Takes an option argument, 
                        # ensuring it has been specified.
                        if [ -n "$2" ]; then
                            tokensha=$2
                            shift
                        else
                            printf 'ERROR: "--clusterip" requires \
                            a non-empty option argument.\n' >&2
                            exit 1
                        fi
                        ;;
        
        --token-sha=?*) # Delete everything up to "=" 
                        # and assign the remainder.
                        tokensha=${1#*=} 
                        ;;
        
        --token-sha=)   # Handle the case of an empty --token-sha=
                        printf 'ERROR: "--token-sha" requires \
                        a non-empty option argument.\n' >&2
                        exit 1
                        ;;
        
        --)             # End of all options.
                        shift
                        break
                        ;;
        
        -?*)
                        printf 'WARN: Unknown option (ignored): %s\n' "$1" >&2
                        ;;

        *)              # Default case: If no more options 
                        # then break out of the loop.
                        break
    esac
shift
done

if [ -z "$masterip" ]; then
    echo "MasterIP is mandatory."
    show_help
    exit    
fi

if [ -z "$token" ]; then
    echo "Token is mandatory."
    show_help
    exit    
fi

if [ -z "$tokensha" ]; then
    echo "Discovery Token SHA is mandatory."
    show_help
    exit    
fi

#Get the machine ip, master ip, cluster ip and the token from the master
machineip=`get_machine_ip`

#Update the host files of the master and minion.
echo Updating the host files...
update_hosts

[[ $kubeversion =~ $kuberegex ]]
# For versions 1.8 and above, swap needs to be disabled
if [[ $? -eq 1 ]]; then
    #Disable swap for Kubernetes 1.8 and above
    echo Disable swap
    disable_swap
fi

#Join the cluster
echo Setting up the Minion using IPAddress: $machineip
echo Setting up the Minion using Token: $token 
setup_k8s_minion
